package com.lingnan.wanxiangxinxun.service.Impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lingnan.wanxiangxinxun.constant.redisConstant;
import com.lingnan.wanxiangxinxun.entity.dto.query.NoticeDTO;
import com.lingnan.wanxiangxinxun.entity.po.Notice;
import com.lingnan.wanxiangxinxun.entity.vo.client.UserNoticeVO;
import com.lingnan.wanxiangxinxun.entity.vo.common.PageVO;
import com.lingnan.wanxiangxinxun.entity.vo.common.Result;
import com.lingnan.wanxiangxinxun.mapper.NoticeMapper;
import com.lingnan.wanxiangxinxun.service.INoticeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 消息通知表 服务实现类
 * </p>
 *
 * @author swl
 * @since 2025-04-30
 */
@Service
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notice> implements INoticeService {

    @Autowired
    private NoticeMapper noticeMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;


    //新增通知（全服通知）
    @Override
    public Result addGlobalNotice(Notice notice) {
        if(notice.getSender().isEmpty()){
            return Result.error("参数错误");
        }
        //notice.setSender("万象新讯官方");
        notice.setCreateTime(LocalDateTime.now());
        noticeMapper.insert(notice);
        return Result.success();
    }


    //新增通知，传入的属性type必须为2（针对某个用户）
    @Override
    public Result addPersonalNotice(Notice notice) {
        try {
            //1.往数据库里面存值
            if (notice.getUserId() == null) {
                return Result.error("用户参数错误");
            }

            notice.setSender("万象新讯官方");
            notice.setCreateTime(LocalDateTime.now());
            noticeMapper.insert(notice);


            //2.往redis里面存键值对（标记该条信息未读）
            String redisKey = redisConstant.USER_UNREAD_PERSONAL_NOTICE_KEY + notice.getUserId(); //这里主键返回了
            redisTemplate.opsForZSet().add(redisKey, notice.getId().toString(), System.currentTimeMillis());

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return Result.success();
    }


    //用户删除已读消息
    @Override
    public boolean removeReadNotice(List<String> ids) {
        int res = noticeMapper.deleteByIds(ids);
        return res > 0;
    }


    //标记某个用户通知已读(从redis中删除这条未读记录)
    @Override
    public boolean markNoticeAsRead(List<String> ids, Integer userId) {
        try{
            if (ids != null && !ids.isEmpty()) {
                String redisKey = redisConstant.USER_UNREAD_PERSONAL_NOTICE_KEY + userId;
                redisTemplate.opsForZSet().remove(redisKey, ids.toArray());
                return true;
            }
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
        return true;
    }



    //条件查询通知
    @Override
    public PageVO<Notice> getNoticeInCondition(NoticeDTO noticeDTO) {
        Notice notice = new Notice();
        BeanUtils.copyProperties(noticeDTO, notice);

        long current = noticeDTO.getCurrent();
        long size = noticeDTO.getSize();

        Page<Notice> page = new Page<>(current, size); // 创建分页对象
        Page<Notice> page_MP = lambdaQuery()
                .eq(notice.getId() != null, Notice::getId, notice.getId())
                .eq(notice.getType() != null, Notice::getType, notice.getType())
                .like(notice.getSender() != null, Notice::getSender, notice.getSender())
                .eq(notice.getUserId() != null, Notice::getUserId, notice.getUserId())
                .ge(noticeDTO.getCreateTime_after() != null, Notice::getCreateTime, noticeDTO.getCreateTime_after())
                .le(noticeDTO.getCreateTime_before() != null, Notice::getCreateTime, noticeDTO.getCreateTime_before())
                .orderByDesc(Notice::getCreateTime)

                .page(page); // 应用分页
        return PageVO.of(page_MP);
    }


    //获取全服通知
    @Override
    public PageVO<Notice> getGlobalNotice(long current, long size) {
        Page<Notice> page_MP = lambdaQuery()
                .eq(Notice::getType, 1)
                .orderByDesc(Notice::getCreateTime)
                .page(new Page<>(current, size));

        return PageVO.of(page_MP);
    }


    //查询某个用户的通知
    @Override
    public PageVO<UserNoticeVO> getNoticeByUserId(Integer userId, long current, long size) {

        Page<Notice> page_MP = lambdaQuery()
                .eq(Notice::getUserId, userId)
                .orderByDesc(Notice::getCreateTime)
                .page(new Page<>(current, size));

        if (page_MP != null) {
            String redisKey = redisConstant.USER_UNREAD_PERSONAL_NOTICE_KEY + userId;
            Set<String> unReadNoticeIdList = redisTemplate.opsForZSet().range(redisKey, 0, -1);

            //转换格式--标记某条消息是否已读
            List<UserNoticeVO> userNoticeVOList = page_MP.getRecords().stream().map(notice -> {
                UserNoticeVO unVO = new UserNoticeVO();
                BeanUtils.copyProperties(notice, unVO);

                //从redis里查询该条消息是否已读
                if (unReadNoticeIdList != null && unReadNoticeIdList.contains(notice.getId().toString())) {
                    unVO.setIsRead(false);
                } else {
                    unVO.setIsRead(true);
                }
                return unVO;
            }).toList();

            long total = page_MP.getTotal();
            long pages = page_MP.getPages();
            return new PageVO<>(total, pages, userNoticeVOList);
        }
        return new PageVO<>();
    }
}
